package model

import (
	"qabx.net/safe-app-center/pkg/utils"
	"strings"
	"time"
)

type TblGateway struct {
	GatewayId  int    `json:"gateway_id,omitempty"`
	GatewayMac string `json:"gateway_mac,omitempty"`
	CreateTime string `json:"create_time"`
	UpdateTime string `json:"update_time"`
	IsDel      int    `json:"is_del,omitempty"`
	PppoeName  string `json:"pppoe_name,omitempty"`
	IsTrue     int    `json:"is_true"`
	AreaNo     string `json:"area_no"`
}

func (s *TblGateway) GetGatewayByMac() (*TblGateway, error) {
	res := &TblGateway{}
	dbClient, _ := utils.GetDbClient()

	_, err := dbClient.Client.Where("is_del =0 and gateway_mac =? ", s.GatewayMac).Limit(1).Get(res)
	return res, err
}

func (s *TblGateway) GetGatewayByPppoeName() (*TblGateway, error) {
	res := &TblGateway{}
	dbClient, _ := utils.GetDbClient()

	_, err := dbClient.Client.Where("is_del =0 and pppoe_name =? ", s.PppoeName).Limit(1).Get(res)
	return res, err
}

func (s *TblGateway) GetGatewayByMacAndAddGateway() (*TblGateway, error) {
	res := &TblGateway{}
	dbClient, _ := utils.GetDbClient()

	_, err := dbClient.Client.Where("is_del =0 and gateway_mac =? ", s.GatewayMac).Limit(1).Get(res)
	if err != nil {
		return nil, err
	} else if res == nil || res.GatewayId == 0 {
		err = s.AddGateway()
		if err != nil {
			return nil, err
		}
		return s, nil
	}
	return res, err
}

func (s *TblGateway) GetGatewayByPppoeNameAndAddGateway() (*TblGateway, error) {
	res := &TblGateway{}
	dbClient, _ := utils.GetDbClient()

	_, err := dbClient.Client.Where("is_del = 0 and pppoe_name =?", s.PppoeName).Limit(1).Get(res)
	if err != nil {
		return res, err
	} else if res == nil || res.GatewayId == 0 {
		err = s.AddGateway()
		if err != nil {
			return res, err
		}
		return s, nil
	}
	return res, err
}

func (s *TblGateway) AddGateway() (err error) {
	dbClient, err := utils.GetDbClient()
	if err != nil {
		return err
	}

	// 初始化字段
	s.CreateTime = time.Now().Format("2006-01-02 15:04:05")
	s.UpdateTime = time.Now().Format("2006-01-02 15:04:05")
	s.IsDel = 0
	s.IsTrue = 1

	// 插入语句
	sql := `INSERT INTO "public"."tbl_gateway" 
    	("gateway_mac", "create_time", "update_time", "is_del", "pppoe_name","is_true","area_no") 
		VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING "gateway_id";`

	// 尝试插入记录
	err = dbClient.Client.DB().QueryRow(sql, s.GatewayMac, s.CreateTime, s.UpdateTime, s.IsDel, s.PppoeName, s.IsTrue, s.AreaNo).Scan(&s.GatewayId)
	if err != nil {
		// 检查是否为唯一约束错误
		if strings.Contains(err.Error(), "duplicate key value") {
			// 查询已有的记录的ID
			sqlQuery := `SELECT "gateway_id" FROM "public"."tbl_gateway" WHERE "pppoe_name" = $1 AND "is_del" = 0 LIMIT 1;`
			err = dbClient.Client.DB().QueryRow(sqlQuery, s.PppoeName).Scan(&s.GatewayId)
			if err != nil {
				return err
			}
			return nil // 成功获取重复记录的ID
		}
		return err
	}
	return nil
}

func (s *TblGateway) AddGatewayDevice(deviceList []*TblDevice) error {
	dbClient, _ := utils.GetDbClient()
	dbClient.StartTransaction()
	for _, v := range deviceList {
		deviceInfo := &TblDevice{}
		//是否存在设备记录
		_, err := dbClient.Client.Where("device_mac=? and is_del=0", strings.ToUpper(v.DeviceMac)).Cols("device_id").Get(deviceInfo)
		if err != nil {
			dbClient.RollbackTransaction()
			return err
		}
		var deviceId int
		if deviceInfo != nil && deviceInfo.DeviceId != 0 {
			deviceId = deviceInfo.DeviceId
		} else {
			sql := `INSERT INTO "public"."tbl_device"("device_mac", "device_ip", "device_ipv6", "device_name", "create_time", "update_time", "is_del") VALUES ($1, $2, $3, $4, $5,$6,$7) RETURNING device_id`
			err = dbClient.Client.DB().QueryRow(sql, strings.ToUpper(v.DeviceMac), v.DeviceIp, v.DeviceIpv6, v.DeviceName, time.Now().Format("2006-01-02 15:04:05"), time.Now().Format("2006-01-02 15:04:05"), 0).Scan(&deviceId)
			if err != nil {
				dbClient.RollbackTransaction()
				return err
			}
		}

		if deviceId == 0 {
			return err
		}
		gatewayDeviceRel := &TblGatewayDeviceRel{
			DeviceId:   deviceId,
			GatewayId:  s.GatewayId,
			IsDel:      0,
			IsOnline:   1,
			IsBlack:    0,
			UpdateTime: time.Now().Format("2006-01-02 15:04:05"),
			CreateTime: time.Now().Format("2006-01-02 15:04:05"),
		}
		_, err = dbClient.Client.Insert(gatewayDeviceRel)
		if err != nil {
			dbClient.RollbackTransaction()
			return err
		}
	}

	dbClient.CommitTransaction()
	return nil

}

// UpdateGatewayDevice 更新网关下设备
func (s *TblGateway) UpdateGatewayDevice(deviceList []*TblDevice) error {
	dbClient, _ := utils.GetDbClient()
	dbClient.StartTransaction()
	for _, v := range deviceList {
		gatewayRel := &TblGatewayDeviceRel{IsOnline: 1, UpdateTime: time.Now().Format("2006-01-02 15:04:05")}
		_, err := dbClient.Client.Cols("is_online", "update_time").Where("gateway_id=? and device_id=?", s.GatewayId, v.DeviceId).Update(gatewayRel)
		if err != nil {
			dbClient.RollbackTransaction()
			return err
		}
		device := &TblDevice{}
		device.DeviceIp = v.DeviceIp
		device.DeviceIpv6 = v.DeviceIpv6
		device.DeviceName = v.DeviceName
		device.UpdateTime = time.Now().Format("2006-01-02 15:04:05")
		_, err = dbClient.Client.Cols("device_ip", "device_name", "device_ipv6", "update_time").Where("device_id=?", v.DeviceId).Update(device)
		if err != nil {
			dbClient.RollbackTransaction()
			return err
		}
	}

	dbClient.CommitTransaction()
	return nil
}

// UpdateGatewayDeviceIsOnline 更新网关下设备在线状态
func (s *TblGateway) UpdateGatewayDeviceIsOnline(isOnline int, deviceIds []int) error {
	res := &TblGatewayDeviceRel{}
	res.GatewayId = s.GatewayId
	res.IsOnline = isOnline
	res.UpdateTime = time.Now().Format("2006-01-02 15:04:05")
	dbClient, _ := utils.GetDbClient()
	_, err := dbClient.Client.Cols("is_online", "update_time").In("device_id", deviceIds).Where("gateway_id=?", s.GatewayId).Update(res)
	return err
}
